有序集合(Zset)

有序集合(zset)和集合同样都是一个字符串类型的集合元素,他们都不允许同样重复的成员。不同的是他拥有一个双精度浮点数来达到从达到小排序的效果,与集合一样可以存储越 40亿个成员。

作为 Redis 几个最为主要的数据类型,他同样拥有针对性的命令,分别为 ZADD 即添加有序集合,他可以添加多个或单个(取决与你的习惯),当然也有 ZRANGE 来进行输出。

1
2
3
4
5
6
7
8
9
10
11
127.0.0.1:6379> ZADD key_zset 1 sql 2 mysql 3 mongoDB 4 redis
(integer) 1
127.0.0.1:6379> ZRANGE key_zset 0 -1 WITHSCORES
1) "sql"
2) "1"
3) "mysql"
4) "2"
5) "mongoDB"
6) "3"
7) "redis"
8) "4"

ZRANGE(从小到大)


ZRANGE 命令会按照数值从小到大来进行排序(具有相同数值的成员将会被按照字典序列来进行排序)

字典序列也就是根据 A、B、C、D 这个序列来进行从小到大来进行划分,也就是根据首字母开头进行排序。

在通过 ZRANGE 命令进行查询的时候,如果不加上 WITHSCORES 返回的是一个元素列表,加上的话返回的则是一个数组列表。

1
2
3
4
5
127.0.0.1:6379> ZRANGE key_zset 0 -1
1) "sql"
2) "mysql"
3) "mongoDB"
4) "redis"

ZRANGEBYLEX

当集合中的元素都以相同的方式进行插入时,那么将会强制按照字典顺序来进行排列(在 Redis 中默认为英文字典 ABC以此类推进行排序)。

在这个命令中他支持有效的 start 以及 stop 修饰符,分别为 [ 以及 - \ + 等。其中 -/+ 分别表示最小和最大字符串,也就是开始和结尾,而 [/( 的区别是输出时是否包含元素 [ 是包含 ( 即不包含。

1
2
3
4
5
6
7
8
9
10
127.0.0.1:6379> ZRANGEBYLEX key_zset - +
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> ZRANGEBYLEX key_zset - (b
1) "a"
127.0.0.1:6379> ZRANGEBYLEX key_zset - [b
1) "a"
2) "b"

ZRANGEBYSCORE

ZRANGEBYSCORE 与 ZRANGEBYLEX 相似,但以我个人感觉更喜欢后者,前者的 -inf+inf 与后者的 -/+ 功能基本一样,区别是多了个 ”inf“,而之后的 [( 功能也很一样,但将需要通过元素来作为参数改为了数值(在ZRANGEBYSCORE 中 [ 并不支持)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
127.0.0.1:6379> ZRANGEBYSCORE key_zset 1 2
1) "one"
2) "two"
127.0.0.1:6379> ZRANGEBYSCORE key_zset -inf 2
1) "day"
2) "one"
3) "two"
127.0.0.1:6379> ZRANGEBYSCORE key_zset -inf (2
1) "day"
2) "one"
127.0.0.1:6379> ZRANGEBYSCORE key_zset -inf +inf
1) "day"
2) "one"
3) "two"
4) "three"

ZSCORE

ZSCORE 命令是上述几个查询命令中最为朴素的命令之一,他主要根据成员名称来返回在其集合中的索引号

1
2
3
4
5
6
7
8
9
10
11
127.0.0.1:6379> ZRANGE zset_one 0 -1 WITHSCORES
1) "day"
2) "0"
3) "one"
4) "1"
5) "two"
6) "2"
7) "three"
8) "3"
127.0.0.1:6379> ZSCORE zset_one "day"
"0"

ZCOUNT

ZCOUNT 同样支持 ( 以及 -inf\+inf这类的表达式,他主要的作用就是计算出集合中的成员数。

1
2
3
4
5
6
7
8
9
10
11
12
127.0.0.1:6379> ZRANGE zset_two 0 -1
1) "day"
2) "one"
3) "two"
4) "three"
5) "four"
127.0.0.1:6379> ZCOUNT zset_two -inf +inf
(integer) 5
127.0.0.1:6379> ZCOUNT zset_two -inf 3
(integer) 4
127.0.0.1:6379> ZCOUNT zset_two -inf (3
(integer) 3

ZREVRANK(从大到小)

ZREVRANK 同样是从大到小根据 0 为起始点进行排序,与 ZREVEANGE 类似,但该命令主要通过成员来返回在其集合中的索引。

1
2
3
4
5
6
7
127.0.0.1:6379> ZRANGE zset_one 0 -1
1) "day"
2) "one"
3) "two"
4) "three"
127.0.0.1:6379> ZREVRANK zset_one "day"
(integer) 3

ZREVRANGEBYSCORE

ZREVRANGEBYSCORE 可以理解为是 ZREVRANK 的延续之作,他除了索引之外还支持 ZRANGEBYLEX 其中的表达式,除此之外还整合了 ZRANGEBYSCORE 来打通信息屏障,通过差异化和颗粒度达到引爆点来聚焦用户感知赛道。

1
2
3
4
5
6
7
8
9
10
11
12
127.0.0.1:6379> ZREVRANGEBYSCORE zset_one 4 1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> ZREVRANGEBYSCORE zset_one 4 (1
1) "three"
2) "two"
127.0.0.1:6379> ZREVRANGEBYSCORE zset_one +inf -inf
1) "three"
2) "two"
3) "one"
4) "day"

ZREVEANGE

ZREVRANGE 是一个更加纯粹的返回字典序列的一个命令,他比 ZRANGE 这群命令显得更加的纯粹和干练,同样是返回集合的作用,该命令只需要指定索引即可,不支持任何华丽胡少的表达式(但支持 redis 自带的)

1
2
3
4
5
127.0.0.1:6379> ZREVRANGE zset_one 0 -1
1) "three"
2) "two"
3) "one"
4) "day"

ZINCRBY

ZINCRBY 简单来讲就是对集合元素中的数组进行增加,假设集合中元素的数组为 0,那么即可通过 ZINCRBY 来进行增加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
127.0.0.1:6379> ZINCRBY key_zset 10 "three"
"13"

127.0.0.1:6379> ZRANGE key_zset 0 -1 WITHSCORES
1) "day"
2) "0"
3) "one"
4) "1"
5) "two"
6) "2"
7) "three"
8) "13"
127.0.0.1:6379> ZINCRBY key_zset -10 "three"
"3"

并集/合集

ZINTERSTORE(合集)

将两个集合之间的交集存储到另一个集合中,需要指定两个集合中相同数的数值(也就是最终相同数所存储到另一个集合中的数量),默认情况下,结果集中的元素数值是这些集合中元素数值之和。

1
2
3
4
5
6
7
8
9
127.0.0.1:6379> ZINTERSTORE zset_key 2 zset_one zset_two
(integer) 3
127.0.0.1:6379> ZRANGE zset_key 0 -1 WITHSCORES
1) "day"
2) "0"
3) "one"
4) "2"
5) "two"
6) "4"

ZUNIONSTORE (并集)

ZUNIONSTORE 与 ZINTERSTORE 的区别就是一个是合集另一个是并集的一字之差,说简单一点就是将两个集合进行合并,相同的元素剔除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
127.0.0.1:6379> ZRANGE zset_two 0 -1
1) "day"
2) "one"
3) "two"
4) "three"
5) "four"
127.0.0.1:6379> ZRANGE zset_one 0 -1
1) "day"
2) "one"
3) "two"
4) "three"
127.0.0.1:6379> ZUNIONSTORE zset_key 2 zset_one zset_two
(integer) 5
127.0.0.1:6379> ZRANGE zset_key 0 -1 WITHSCORES
1) "day"
2) "0"
3) "one"
4) "2"
5) "four"
6) "4"
7) "two"
8) "4"
9) "three"
10) "6"

但这样会造成集合中索引的相同,为了避免这类事情的发生我们可以自定义权重或和来解决 ZUNIONSTORE zset_key 2 zset_one zest_two WEIGHTS 2 3 [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX],这同样在 ZINTERSTORE 命令中适用。

ZRANK

ZRANK 简单来说就单纯的是一个可以根据其集合成员来返回其索引的作用,如果其成员不存在则会返回 nil

1
2
3
4
5
6
7
8
9
10
11
12
13
127.0.0.1:6379> ZRANK zset_one "day"
(integer) 0
127.0.0.1:6379> ZRANK zset_one "one"
(integer) 1
127.0.0.1:6379> ZRANGE zset_one 0 -1 WITHSCORES
1) "day"
2) "0"
3) "one"
4) "1"
5) "two"
6) "2"
7) "three"
8) "3"

ZREM

ZREM 没有像后续几条命令一样那么否有诗书气自华,他主要根据成员来针对单个集合进行删除,在 Redis => 2.4 版本中支持删除多个成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
127.0.0.1:6379> ZADD key_zset 0 day 1 one 2 two 3 three 3 four
(integer) 5
127.0.0.1:6379> ZRANGE key_zset 0 -1
1) "day"
2) "one"
3) "two"
4) "four"
5) "three"
127.0.0.1:6379> ZREM key_zset "four"
(integer) 1
127.0.0.1:6379> ZRANGE key_zset 0 -1
1) "day"
2) "one"
3) "two"
4) "three"
127.0.0.1:6379>

ZREMRANGEBYLEX

该命令与 ZREM 相比起来就非常的丰富,他支持了一些较为简单的 Redis 表达式([ 包括自己),适合多个成员一起删除,当然你也可以选择删除单个(弊端就是你删除不了第一个和倒数第二个成员)。

但是 ZREMRANGEBYLEX 的弊端就是需要该集合索引都是一样的才可以进行删除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
127.0.0.1:6379> ZRANGE key_zset 0 -1 WITHSCORES
1) "day"
2) "0"
3) "four"
4) "0"
5) "one"
6) "0"
7) "three"
8) "0"
9) "two"
10) "0"
127.0.0.1:6379> ZREMRANGEBYLEX key_zset [day [one
(integer) 3
127.0.0.1:6379> ZRANGE key_zset 0 -1 WITHSCORES
1) "three"
2) "0"
3) "two"
4) "0"

ZREMRANGEBYRANK

该命令同样非产简约优雅,通过 start\stop 的操作可以快速删除多个集合中的成员,但劣势也一样展现出来,他并不能删除单个成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
127.0.0.1:6379> ZRANGE key_zset 0 -1 WITHSCORES
1) "day"
2) "0"
3) "one"
4) "1"
5) "two"
6) "2"
7) "three"
8) "3"
9) "four"
10) "5"
127.0.0.1:6379> ZREMRANGEBYRANK key_zset 3 5
(integer) 2
127.0.0.1:6379> ZRANGE key_zset 0 -1 WITHSCORES
1) "day"
2) "0"
3) "one"
4) "1"
5) "two"
6) "2"

ZREMRANGEBYSCORE

ZREMRANGEBYSCORE Reids 的有序列表删除命令就发展的非常特别且简单优雅,他同样适合于多个成员的删除操作,与前者不同的是到他这开始支持了 -inf (不包含该成员) 这类的表达式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
127.0.0.1:6379> ZRANGE key_zset 0 -1 WITHSCORES
1) "day"
2) "0"
3) "one"
4) "1"
5) "two"
6) "2"
127.0.0.1:6379> ZREMRANGEBYSCORE key_zset -inf (1
(integer) 1
127.0.0.1:6379> ZRANGE key_zset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "two"
4) "2"

本文使用《江雪分析公开知识存储库知识共享许可证》进行发布